import com.google.api.client.util.DateTime;
import com.google.api.services.calendar.model.Event;
import com.google.api.services.calendar.model.EventDateTime;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.StringTokenizer;
import java.util.TimeZone;

/**
 * @author Martin
 * 
 */
public class ICalParser {
  private static final String ICAL_TEST_URL_1 = // U12 - Fruejahr 2014
      "http://www.fussballoesterreich.at/netzwerk/icalendar/670725461856634215_100092~967627949199082487-T-7XtNLNZ4.ics";
  private static final String ICAL_TEST_URL_2 = // KM/Res
      "https://www.google.com/calendar/ical/u8fa4c0h280v986uv99mpeh9p8%40group.calendar.google.com/public/basic.ics";

  private static final String ICAL_TEST_URL_IN_USE = ICAL_TEST_URL_1;


  public static void main(String[] args) {
    try {
      String content = getContentOfFile(ICAL_TEST_URL_IN_USE);
      Event[] events = getEventsForICal(ICAL_TEST_URL_IN_USE);
      MySingleEvent[] mySingleEvents = new MySingleEvent[events.length];
      int i = 0;
      for (Event event : events) {
        MySingleEvent mySingleEvent = new MySingleEvent(event, "TEST");
        mySingleEvents[i++] = mySingleEvent;
        if (mySingleEvent.id != null) {
          System.out.println(mySingleEvent.shortCalendarName + ": " + mySingleEvent.startDateString
              + " - " + mySingleEvent.homeTeam + " - " + mySingleEvent.awayTeam + " (in "
              + mySingleEvent.locationString + ") (ref: " + mySingleEvent.referee
              + ", description: " + mySingleEvent.description + ")");
        }
      }
    } catch (Throwable t) {
      t.printStackTrace();
    }
    System.exit(1);
  }

  public static Event[] getEventsForICal(String url) throws Exception {
    String content = getContentOfFile(url);
    return parseFileContent(content);
  }

  private static String getContentOfFile(String url) throws Exception {
    BufferedReader reader = null;
    StringBuffer sb = new StringBuffer();

    try {
      URL site = new URL(url);
      reader = new BufferedReader(new InputStreamReader(site.openStream(), "UTF-8"));

      String curLine;
      while ((curLine = reader.readLine()) != null) {
        sb.append(curLine);
        sb.append("\r\n");
      }
    } finally {
      if (reader != null) {
        reader.close();
      }
    }

    return sb.toString();
  }


  private static Event[] parseFileContent(String content) throws ParseException {
    List<Event> eventList = new LinkedList<Event>();

    StringTokenizer st = new StringTokenizer(content, "\n");
    while (st.hasMoreElements()) {
      String curLine = st.nextToken();
      if (curLine.startsWith("BEGIN:VEVENT")) {
        eventList.add(parseEventContent(st));
      }
    }

    return eventList.toArray(new Event[eventList.size()]);
  }


  private static Event parseEventContent(StringTokenizer st) throws ParseException {
    Event event = new Event();
    String summaryStr = new String();
    String locationStr = new String();
    String descriptionStr = new String();
    boolean lastLineWasSummary = false;
    boolean lastLineWasLocation = false;
    boolean lastLineWasDescription = false;

    while (st.hasMoreElements()) {
      String curLine = st.nextToken().replace("\r", "");
      if (curLine.startsWith("END:VEVENT")) {
        break;
      } else if (curLine.startsWith("SUMMARY:")) {
        summaryStr = curLine.substring("SUMMARY:".length());
        lastLineWasSummary = true;
        lastLineWasLocation = false;
        lastLineWasDescription = false;
      } else if (curLine.startsWith("LOCATION:")) {
        locationStr = curLine.substring("LOCATION:".length());
        lastLineWasSummary = false;
        lastLineWasLocation = true;
        lastLineWasDescription = false;
      } else if (curLine.startsWith("DESCRIPTION:")) {
        descriptionStr = curLine.substring("DESCRIPTION:".length());
        lastLineWasSummary = false;
        lastLineWasLocation = false;
        lastLineWasDescription = true;
      } else if (curLine.startsWith("DTSTART:")) {
        String startStr = curLine.substring("DTSTART:".length());
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'");
        dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
        EventDateTime eventDateTime = new EventDateTime();
        Date date = dateFormat.parse(startStr);
        DateTime dateTime = new DateTime(date);
        eventDateTime.setDateTime(dateTime);
        event.setStart(eventDateTime);
        lastLineWasSummary = false;
        lastLineWasLocation = false;
        lastLineWasDescription = false;
      } else if (curLine.startsWith(" ")) {
        if (lastLineWasSummary) {
          summaryStr += curLine.substring(1);
        } else if (lastLineWasLocation) {
          locationStr += curLine.substring(1);
        } else if (lastLineWasDescription) {
          descriptionStr += curLine.substring(1);
        }
      } else {
        lastLineWasSummary = false;
        lastLineWasLocation = false;
        lastLineWasDescription = false;
      }
    }

    event.setSummary(summaryStr);
    event.setLocation(locationStr);

    // replace "\n"
    while (descriptionStr.indexOf("\\n") != -1) {
      int idx = descriptionStr.indexOf("\\n");
      descriptionStr = descriptionStr.substring(0, idx) + "\n" + descriptionStr.substring(idx + 2);
    }
    event.setDescription(descriptionStr);

    return event;
  }
}
